#ifndef AGGREGATIONFUNCTIONMODELGENERATOR_H_JM_20130222
#define AGGREGATIONFUNCTIONMODELGENERATOR_H_JM_20130222


#include "../generators/ModelGenerator.h"
#include "../generators/Slices.h"
#include "../boxes/DefaultGroupDefinitions.h"

#include "DataInputModelPartGenerator.h"
#include "DataOutputModelPartGenerator.h"

namespace jm4bbx {

	class  AggregationFunctionModelGenerator  : public ModelGenerator {
	public:

		AggregationFunctionModelGenerator(
			const int N, // parallelism level
			const std::string& inputBoxName,
			const InputBoxConfiguration& inpBoxConf,
			const std::string& aggFunBoxName,
			const std::string& resultBoxName,
			const std::string& outputBoxName) {
				/// Input

				DataInputModelPartGenerator inGen;
				InputBoxConfiguration confs[1] = {inpBoxConf};
				inGen.addBoxes(this, inputBoxName, confs, 1, N, true, true);
				
				/// prevedenie agragcnej funkcie
				BoxDescriptorPtr aggFunBox = addBox(aggFunBoxName, N);

				BoxDescriptorPtr aggResultBox = addBox(resultBoxName, 
					genBoxParam("inputs", N) +
					genBoxParam("signal_out", 1));

				/// Output
				DataOutputModelPartGenerator oGen;
				oGen.addBoxes(this, outputBoxName, "", 1);
				//--------------------------------------------------------------
				//--------------------------------------------------------------
				//-------------------------------------------------------------- 

				inGen.addSlices(this, "IntegerKeyRecord");

				addSlice(new ForkSlice(inGen.getForkDataBox(0)->getBoxId(), 
					aggFunBox->getBoxIds(), N, D_O, D_I, 
					genTypes("IntegerKeyRecord", 1)));

				addSlice(new MergeSlice(aggFunBox->getBoxIds(), 
					aggResultBox->getBoxId(), N, D_O, D_I, 
					genTypes("int", 1)));	

				addSlice(new PlainSlice(aggResultBox->getBoxId(), 
					oGen.getOutputBoxes()->getBoxId(), D_O, D_I, 
					genTypes("IntegerKeyRecord", 1)));

				addSlice(new PlainSlice(aggResultBox->getBoxId(), 
					oGen.getTimerReportBox()->getBoxId(), S_O, S_I));

				oGen.addSlices(this);
		}

	};

} // namespace jm4bbx

	

#endif
